//
// Created by superzou on 2019/11/5.
//
#include <list>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <functional>
#include <vector>
#include <iostream>
#include <functional>
#include "LineShadow.h"
#include "utils.h"
#include "imagemanager.h"
#include <string>
#include <filesystem>
using namespace std;
namespace  fs= filesystem;




LineShadow::LineShadow()
    :imageManager(new ImageManager())
{}

void LineShadow::saveImages(const path& dir, const path& imageName)
{
    assert(!dir.empty());
    assert(!imageName.empty());

    const string mask_image_path = dir / imageName;
    auto & mask = imageManager->getImages()[1];

    assert(!mask.empty());
    cv::imwrite(mask_image_path, mask);
    cout<<"saving mask"<<endl;
}
cv::Mat LineShadow::getOrigin(){
    if(imageManager->getImages().size()>=1){
        return imageManager->getImages()[0];
    }else{
        throw "no any image";
    }

}
cv::Mat LineShadow::getMask(){
    if(imageManager->getImages().size()>=2){
        return imageManager->getImages()[1];
    }
    else{
            throw "no mask";
        }
}



void LineShadow::addPoint(const cv::Point &pos) {
    imageManager->getPoints().push_back(pos);
    imageManager->getPoints_back_up().push_back(pos);
}

void LineShadow::addPoint(const QPoint &pos) {
    cv::Point p(pos.x(), pos.y());
    imageManager->getPoints().push_back(p);
    imageManager->getPoints_back_up().push_back(p);
}
void LineShadow::printPoints() {
    for( auto &x:imageManager->getPoints())
        cout<<x<<"\t";
    cout<<endl;
}


void LineShadow::clearPoints() {
    imageManager->getPoints().clear();
}

void LineShadow::addImages(const cv::Mat &img) {
    imageManager->getImages().push_back(img);
    cout<<"current has ("<<imageManager->getImages().size()<<") images"<<endl;
}

void LineShadow::clearImages(){
    imageManager->getImages().clear();
}
void LineShadow::drawOnClick(const cv::Scalar &color){
    if(imageManager->getPoints().empty())
        return;
    for(auto &img : imageManager->getImages())
    {
        line(img, imageManager->getPoints()[0], imageManager->getPoints()[0], color, imageManager->getDrawSize());
    }

    clearPoints();
}

void LineShadow::drawOnMove(const cv::Scalar &color){

    if(static_cast<int>(imageManager->getPoints().size()) > imageManager->getstepSize())
    {
        for(auto &img : imageManager->getImages())
        {
            auto iter1 = imageManager->getPoints().begin();
            auto iter2 = imageManager->getPoints().begin();
            ++iter2;
            for(; iter2!=imageManager->getPoints().cend(); ++iter1,++iter2)
            {
                cv::Point p1 = (*iter1);
                cv::Point p2 = (*iter2);
                //circle(img, p2, 1, Scalar(0, 0, 255)); //描以后的点
                line(img, p1, p2, color, imageManager->getDrawSize());
                //line(img,p1 , p2, );//与前一点进行连线  参数：画图板背景、第一个点位置、第二个点位置、BGR颜色
                //line(mask, p1, p2, Scalar(255, 255, 255), 2);//与前一点进行连线  参数：画图板背景、第一个点位置、第二个点位置、BGR颜色
            }

        }
        clearPoints();
    }
}

void LineShadow::drawOnRelease(const cv::Scalar &color){

    for(auto &img : imageManager->getImages())
    {
        auto iter1 = imageManager->getPoints_back_up().begin();
        auto iter2 = imageManager->getPoints_back_up().begin();
        ++iter2;
        for(; iter2!=imageManager->getPoints_back_up().cend(); ++iter1,++iter2)
        {
            cv::Point p1 = (*iter1);
            cv::Point p2 = (*iter2);
            //circle(img, p2, 1, Scalar(0, 0, 255)); //描以后的点
            line(img, p1, p2, color, imageManager->getDrawSize());
            //line(img,p1 , p2, );//与前一点进行连线  参数：画图板背景、第一个点位置、第二个点位置、BGR颜色
            //line(mask, p1, p2, Scalar(255, 255, 255), 2);//与前一点进行连线  参数：画图板背景、第一个点位置、第二个点位置、BGR颜色
        }
    }
        clearPoints();
        imageManager->getPoints_back_up().clear();
}


void LineShadow::draw(int x, int y, const cv::Scalar& color, int flags)
{

    addPoint(cv::Point(x, y));
    if(flags == ON_CLICK)
        drawOnClick(color);
    else if(flags == ON_MOVING)
        drawOnMove(color);
    else if(flags == ON_RELEASE){
        drawOnRelease(color);
    }
}
